import { type Ref } from "vue";
import { useCanvas } from "../common";
import { Star } from "./Star";
import { Circle } from "./Circle";

const { clear, setContext } = useCanvas();

export class Stage {
  freq_render: number;
  velocity_dim: number;
  velocity_move: number;
  colors: string[];
  star: Star;
  circle: Circle;
  frame: number;
  width: Ref<number>;
  height: Ref<number>;

  constructor(freq_render: number, velocity_dim: number, velocity_move: number, colors: string[]) {
    this.freq_render = freq_render;
    this.velocity_dim = velocity_dim;
    this.velocity_move = velocity_move;
    this.colors = colors;
    this.frame = 0;
    this.star = new Star();
    this.circle = new Circle();
    this.width = ref(window.innerWidth);
    this.height = ref(window.innerHeight);
    this.setStyle();
  }
  setStyle() {
    this.width.value = window.innerWidth;
    this.height.value = window.innerHeight;
  }
  enterFrame() {
    requestAnimationFrame(() => this.enterFrame());
    clear();
    this.setStyle();
    this.star.enterFrame();
    this.circle.enterFrame();
  }
  addStar(e: MouseEvent) {
    this.frame++;
    if (this.frame > 1e6) this.frame = 0;
    if (this.frame % this.freq_render !== 0) return;
    const x = e.clientX;
    const y = e.clientY;
    const color = this.colors[Math.floor(Math.random() * this.colors.length)];
    const size = Math.random() * 10 + 5;
    this.star.add(x, y, color, size, this.velocity_dim, this.velocity_move);
  }
  addCircle(e: MouseEvent) {
    const x = e.clientX;
    const y = e.clientY;
    const color = this.colors[Math.floor(Math.random() * this.colors.length)];
    this.circle.add(x, y, color);
  }
  start(cvs: Ref<HTMLCanvasElement | null>) {
    const init = () => {
      setContext(cvs.value?.getContext("2d"));
      this.enterFrame();
    };
    onMounted(init);
    addEventListener("resize", this.setStyle);
    addEventListener("mousemove", (e) => this.addStar.call(this, e));
    addEventListener("mousedown", (e) => this.addCircle.call(this, e));
  }
}
